package cn.hg.jfsa.common;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Model;

public class JfsaLogManager implements Runnable {

	private static final JfsaLogManager me = new JfsaLogManager();
	private static Thread THREAD;

	public static JfsaLogManager me () {
		return JfsaLogManager.me;
	}

	private boolean isLogEnabled = false;
	private Log log = Log.getLog(JfsaLogManager.class);
	private List<Model<?>> logActionList = new ArrayList<>();
	private int logLimit = 20;
	private long logTime = 1 * 60 * 1000L;

	/**
	 * 私有代构造方法，不允许创建
	 */
	private JfsaLogManager () {}

	public void add (Model<?> log) {

		if (!this.isLogEnabled) {
			return;
		}

		synchronized (this.logActionList) {
			this.logActionList.add(log);
		}

		// 如果缓存数量大于限制数量，则写数据库
		if (this.logActionList.size() >= this.logLimit) {
			this.flush();
		}

	}

	public void flush () {

		synchronized (this.logActionList) {

			if (this.logActionList.size() == 0) {
				return;
			}

			// 启动数据库线程
			Db.tx(new IAtom() {

				@Override
				public boolean run () throws SQLException {

					if (JfsaLogManager.this.logActionList.size() == 0) {
						return true;
					}

					JfsaLogManager.this.log.debug("写日志到数据库。。。");

					for (Model<?> log : JfsaLogManager.this.logActionList) {
						log.save();
					}

					JfsaLogManager.this.logActionList.clear();
					return true;
				}

			});
		}

	}

	public int getLogLimit () { return this.logLimit; }

	public long getLogTime () { return this.logTime; }

	public boolean isLogEnabled () { return this.isLogEnabled; }

	@Override
	public void run () {

		while (true) {

			try {
				Thread.sleep(this.logTime);

				if (this.isLogEnabled) {
					this.flush();
				}

			}
			catch (InterruptedException e) {
				this.log.warn("日志管理器线程错误：", e);
			}

		}

	}

	public void setLogEnabled (boolean logEnabled) {
		this.isLogEnabled = logEnabled;

		if (this.isLogEnabled) {
			JfsaLogManager.THREAD = new Thread(this);
			JfsaLogManager.THREAD.start();
		} else {
			JfsaLogManager.THREAD.interrupt();
			JfsaLogManager.THREAD = null;
		}

	}

	/**
	 * 设置日志缓存数
	 *
	 * @param limit
	 */
	public void setLogLimit (int limit) { this.logLimit = limit; }

	public void setLogTime (int time) { this.logTime = time * 60 * 1000; }

}
